.TITLE DRQIO .IDENT /15.06/ ; ; Copyright (c) 1995-1999 by Mentec, Inc., U.S.A. ; All rights reserved ; ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED ; OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; D. N. CUTLER 8-OCT-73 ; ; MODIFIED FOR RSX-11M-PLUS VERSION 2.1 BY: ; ; J. R. KAUFFMAN ; J. M. LAWLER ; T. LEKAS ; B. S. MCCARTHY ; ; MODIFIED FOR RSX-11M-PLUS VERSION 3.0 BY: ; ; H. HUANG ; S. C. ADAMS ; S. M. THOMAS ; J. W. BERZLE ; B. S. MCCARTHY ; L. B. MCCULLEY ; ; MODIFIED BY: ; ; K. L. NOEL 06-JAN-87 V15.00 ; ; KLN032 -- ADD IMPLICIT LUN ASSIGNMENTS ; ; K. L. NOEL 05-MAR-87 V15.01 ; ; KLN036 -- ADD SUPPORT FOR REMOTE OVERLAYS ; ; K. L. NOEL 11-MAR-87 V15.02 ; ; KLN038 -- BYPASS CHECKS FOR NON-MOUNTED MOUNTABLE DEVICES ; ON REMOTE SYSTEMS ; ; K. L. NOEL 6-APR-87 V15.03 ; ; KLN040 -- FIX IMPLICIT ALUN CALL TO A JUMP ; ; K. L. NOEL 16-JUN-87 V15.04 ; ; KLN054 -- ALLOCATE CPRBUF PACKET FOR KILL I/O FUNCTIONS ; ; ERIC POSTPISCHIL 20-JUL-87 15.05 ; edp057 -- REMOVE CORRECT NUMBER OF ITEMS FROM KERNEL STACK ; WHEN BACKING UP TASK'S PC. ; ; Paul K. M. Weiss 2-May-90 15.06 ; PKW195 -- Treat overlays correctly for CPR ; ; MACRO LIBRARY CALLS ; .MCALL F11DF$,HWDDF$,PKTDF$,SHDDF$,TCBDF$,PCBDF$,UCBDF$ .MCALL BGCK$A .MCALL CPRDF$ F11DF$ ;DEFINE FILES-11 CONTROL BLOCK OFFSETS HWDDF$ ;DEFINE HARDWARE REGISTERS PKTDF$ ;DEFINE I/O PACKET OFFSETS SHDDF$ ;DEFINE SHADOW RECORDING OFFSETS TCBDF$ ;DEFINE TASK CONTROL BLOCK OFFSETS PCBDF$ ;DEFINE PARTITION CONTROL BLOCK OFFSETS UCBDF$ ;DEFINE UNIT CONTROL BLOCK OFFSETS CPRDF$ ;DEFINE COPROCESSOR DEFINITIONS ; ; LOCAL SYMBOLS ; MAP6 = 140000 ;+ ; **-$DRQIO-QUEUE I/O REQUEST ; **-$DRQIW-QUEUE I/O REQUEST AND WAIT. ; ; THESE DIRECTIVES INSTRUCT THE SYSTEM TO PLACE AN I/O REQUEST IN A ; QUEUE OF PRIORITY ORDERED REQUESTS FOR A DEVICE-UNIT SPECIFIED BY ; A LOGICAL UNIT NUMBER. IN ADDITION, IF THE DIRECTIVE IS QIO AND ; WAIT AND AN EVENT FLAG IS SPECIFIED, THE TASK IS PUT INTO A WAIT STATE ; FOR THE SPECIFIED EVENT FLAG. ; ; DPB FORMAT: ; ; WD. 00 -- DIC(1./3.),DPB SIZE(12.). ; WD. 01 -- I/O FUNCTION CODE. ; WD. 02 -- LUN AND UNUSED BYTE. ; WD. 03 -- EVENT FLAG NUMBER AND PRIORITY (PRIORITY IS IGNORED). ; WD. 04 -- ADDRESS OF I/O STATUS BLOCK. ; WD. 05 -- ADDRESS OF AST SERVICE ROUTINE. ; WD. 06 -- PARAMETER 1. ; WD. 07 -- PARAMETER 2. ; WD. 10 -- PARAMETER 3. ; WD. 11 -- PARAMETER 4. ; WD. 12 -- PARAMETER 5. ; WD. 13 -- PARAMETER 6. ; ; INPUTS: ; ; R2=ADDRESS OF THE TASK STATUS WORD OF THE CURRENT TASK. ; R3=ADDRESS OF THE I/O FUNCTION CODE IN THE DPB. ; R4=ADDRESS OF THE HEADER OF THE CURRENT TASK. ; R5=ADDRESS OF THE TCB OF THE CURRENT TASK. ; ; OUTPUTS: (DIRECTIVE STATUS AND PS RETURNED TO TASK) ; ; C=0 IF DIRECTIVE IS SUCCESSFULLY COMPLETED. ; DIRECTIVE STATUS OF +1 IS RETURNED. ; C=1 IF DIRECTIVE IS REJECTED. ; DIRECTIVE STATUS OF 'D.RS5' IS RETURNED IF SPECIFIED ; LUN IS NOT ASSIGNED. ;- .ENABL LSB $DRQIO::MOV (R3)+,-(SP) ;SAVE I/O FUNCTION CODE CALL $MPLUN ;MAP LUN TO UCB ADDRESS BCC 10$ ;IF CC LUN ASSIGNED .IF DF C$$DFB&C$$RTB ;RUN TIME BINDING OF LUNS BIT #T4.DFB,T.ST4(R5) ;TASK HAVE DEFERRED BINDING? BEQ 5$ ;IF EQ NO BIT #F5.RTB,$FMSK5 ;SYSTEM SUPPORT RUN TIME BINDING? BEQ 5$ ;IF EQ NO TST (SP)+ ;REMOVE I/O FUNCTION CODE FROM STACK JMP $IMASG ;DO IMPLICIT ALUN .ENDC ;C$$DFB&C$$RTB 5$: DRSTS D.RS5 ;SET DIRECTIVE STATUS 10$: .IF DF R$$AMD ;AUTOMOUNT/DISMOUNT CMP $VERTK,R5 ;QIO FROM VERIFICATION TASK ? BEQ 14$ ;IF EQ, YES - BREAKTHROUGH STALL I/O ASSUME US.SIO,200 TSTB U.ST2(R2) ;STALL I/O IN PROGRESS ? BMI 13$ ;IF MI, YES - DON'T QUEUE I/O .ENDC ; DF R$$AMD BIT #1,(R1) ;OPERATION PENDING ? BEQ 14$ ;IF EQ NO 13$: ADD #12,SP ; REMOVE FUNCTION, RETURN AND +1 FROM STACK. 135$: SUB #2,$UMPC ;BACKUP TASK PC TO RE-EXECUTE CALLR $TKWSE ;WAITFOR SIGNIFICANT EVENT 14$: .IF DF C$$RTK ;REMOTE TASK SUPPORT BIT #F5.RTK,$FMSK5 ;REMOTE TASKS TURNED ON? BEQ 145$ ;IF EQ NO CMPB 1(SP),#IO.KIL/256. ;IS THIS I/O KILL? BNE 145$ ;IF NE NO CMP (R2),$XXLOW ;IS I/O KILL FOR A GENERIC UCB BLO 145$ ;IF LO, NO CMP (R2),$XXHGH ;IS I/O KILL FOR A GENERIC UCB BHI 145$ ;IF HI, NO MOV R3,-(SP) ;SAVE R3 MOV R0,-(SP) ; AND R0 MOV R1,-(SP) ; AND R1 MOV #AL$SWS,R0 ;CALL IS FROM SYSTEM STATE MOV #1,R1 ;ONE BLOCK TO ALLOCATE CALL $CPALO ;GET PACKET BCC 143$ ;IF CC, ALLOCATION OKAY ADD #14,SP ;GET RID OF JUNK ON THE STACK BR 135$ ;GO TO BACK UP USER'S PC 143$: MOV R0,$CPPKT ;SAVE ADDRESS OF PACKET MOV (SP)+,R1 ;RESTORE R1 MOV (SP)+,R0 ; AND R0 MOV (SP)+,R3 ; AND R3 CLR $CPLUN ; MOVB -2(R3),$CPLUN ;STORE LUN NUMBER TO KILL I/O ON .ENDC ;C$$RTK 145$: BIT #DV.ISP!DV.OSP,U.CW1(R2) ;SPOOLED DEVICE? BEQ 16$ ;IF EQ NO CMP U.ATT(R2),R5 ;IS ISSUING TASK THE DESPOOLER? BEQ 155$ ;IF EQ YES, I/O TO REAL DEVICE BITB #US.MNT,U.STS(R2) ;SPOOLED DEVICE MOUNTED ? BNE 15$ ;IF NE NO (US.MNT IS DEVICE NOT MOUNTED) CMP U.ACP(R2),R5 ;ISSUING TASK THE DEVICE'S ACP ? BEQ 155$ ;IF EQ YES, I/O TO REAL DEVICE 15$: CMPB 1(SP),#IO.WLB/256. ;WRITE LOGICAL FUNCTION NOT BY DSPLR? BNE 16$ ;IF NE NO DRSTS D.RS16 ;PRIVILEGE VIOLATION 155$: MOV R2,R0 ;DIRECT I/O TO ACTUAL SPOOLED DEV 16$: MOV (R0),R2 ;GET DCB ADDRESS TST D.DSP(R2) ;IS THE DRIVER RESIDENT? BNE 17$ ;IF NE YES DRSTS D.RS6 ;SET DIRECTIVE STATUS 17$: MOV R0,-(SP) ;SAVE POINTER TO UCB MOV R1,-(SP) ;SAVE POINTER TO SECOND LUN WORD MOVB (R3),-(SP) ;SAVE EVENT FLAG NUMBER CALL $CEFNG ;CONVERT EVENT FLAG NUMBER BIC #1,R1 ;CLR GRP GLOBAL 2ND WORD INDICATOR BIC R0,(R1) ;CLEAR SPECIFIED EVENT FLAG MOV R3,-(SP) ;SAVE ADDRESS OF I/O STATUS BLOCK ADDRES MOV (R3),R0 ;GET ADDRESS OF I/O STATUS BLOCK ADDRESS BEQ $DQLM2 ;IF EQ NO I/O STATUS BLOCK SPECIFIED $DQLM1::CLR -(SP) ;ZERO I/O STATUS BLOCK MTPD$ (R0)+ ; CLR -(SP) ; MTPD$ (R0) ; $DQLM2::CALL $ALPKT ;ALLOCATE AN I/O PACKET .IF DF A$$CNT MOV R0,-(SP) ;SAVE PACKET ADDRESS MOV T.ACN(R5),R0 ;LOCATE ACCOUNTING BLOCKS OF TASK BEQ 20$ ;IF EQ, NO ACCOUNTING ON TASK MOV #B.QIO,R1 ;OFFSET TO QIO COUNT FIELD CALL $ADAT1 ;INCREMENT QIO COUNT 20$: MOV (SP)+,R0 ;RESTORE PACKET ADDRESS TO R0 .ENDC TALLY$ B.QIOC,XA$$IO,CPU ;COUNT AN I/O INITIATION FOR THIS CPU .IF DF S$$HDW MOV #DV.DIR!DV.F11,R3 ;SEE IF DEVICE SUPPORTS SHADOWING ; ; THE FOLLOWING INSTRUCTION DEPENDS ON THE UCB ADDRESS FOR THE ; CURRENT UCB BEING AT OFFSET 6(SP). ; MOV 6(SP),R1 ;GET UCB ADDRESS BIC U.CW1(R1),R3 ;ARE ALL BITS SET? BNE 23$ ;IF NE NO -- EXIT BIT #DV.SQD,U.CW1(R1) ;COULD IT BE MAGTAPE? BNE 23$ ;IF NE YES -- EXIT MOV U.UMB(R1),R1 ;GET UMB ADDRESS BEQ 23$ ;IF EQ NO UMB ; ; THE REPLACEMENT CONTROL TASK MUST BE SPECIAL CASED FOR SHADOWING. ; IT IS THE ONLY TASK THAT MAY READ OR WRITE EITHER THE PRIMARY OR ; THE SECONDARY DEVICE WITHOUT ITS FUNCTION BEING SHADOWED. ; CMP $RCTPT,R5 ;IS THIS I/O FROM RCT...? BEQ 23$ ;IF EQ YES CMP 6(SP),M.UCBS(R1) ;PRIMARY UCB? BEQ 21$ ;IF EQ YES CALL $DEPKT ;DEALLOCATE I/O PACKET DRSTS D.RS16 ;PRIVILEGE VIOLATION ; ; DEVICE SUPPORTS SHADOW RECORDING AT THIS TIME. ALLOCATE THE ML ; NODE AND LINK IT IN THE LIST AT M.LHD. ; 21$: BIT #MS.MDA,M.STS(R1) ;CAN WE ALLOCATE NEW ONES? BNE 23$ ;IF NE NO MOV R0,-(SP) ;SAVE CURRENT I/O PACKET MOV R1,-(SP) ;SAVE UMB ADDRESS MOV #ML.LGH,R1 ;SET LENGTH OF ML NODE CALL $ALOCB ;GET PACKET BCC 22$ ;IF CC GOT SPACE ; ; NOT ENOUGH SPACE FOR THE ML NODE IN THE SYSTEM POOL. SEEMS ; A SHAME TO KILL THE I/O AFTER GETTING THE FIRST PACKET, AND ; NOT THE SECOND. MAYBE THE FINAL ANSWER IS TO LET THE FIRST ; GO THRU AND ONLY CONSIDER IT A PROBLEM IF IT WAS A WRITE OR ; A READ THAT FAILED. FROM THE STATISTICS, IT WOULD SEEM THAT ; THIS WOULD COVER THE VAST MAJORITY OF THE CASES (I.E. MOST ; QIO FUNCTIONS ARE READS). ; ; FOR THE TIME BEING, IF WE CAN'T GET THE RESOURCES NOW, FORGET IT. ; TST (SP)+ ;REMOVE UMB ADDRESS MOV (SP)+,R0 ;GET I/O PACKET ADDRESS CALL $DEPKT ;DEALLOCATE I/O PACKET DRSTS D.RS1 ;ALLOCATION FAILURE 22$: MOV R0,R1 ;COPY ML NODE ADDRESS CLR (R0)+ ;CLEAR LINK WORD MOVB #ML.LGH,(R0)+ ;ML.LEN SET LENGTH MOVB #MT.PKT,(R0)+ ;ML.TYP SET TYPE CLR (R0)+ ;ML.DNC/UNUSED SET DONE COUNT MOV 2(SP),(R0)+ ;ML.PRI SET PRIMARY I/O PACKET ADDRESS MOV (SP)+,R0 ;GET UMB ADDRESS MOV M.LHD(R0),(R1) ;LINK NEW NODE TO PREVIOUS FIRST MOV R1,M.LHD(R0) ;POINT LISTHEAD TO NEW NODE MOV (SP)+,R0 ;GET OLD I/O PACKET BACK 23$: ;REFERENCE LABEL .ENDC .IF DF R$$LKL CLR I.PRM+16(R0) ;INITIALLY CLEAR LOCK ENTRY POINTER .ENDC ADD #I.AADA,R0 ;POINT TO ATTACHEMENT DESCRIPTOR POINTERS MOV R0,$ATTPT ;SAVE POINTER FOR $CKBFX ROUTINES CLR (R0)+ ;CLEAR FIRST ATT DESC PTR CLR (R0) ;SECOND SUB #I.AADA+2,R0 ;POINT BACK TO START OF I/O PACKET INCB T.IOC(R5) ;INCREMENT I/O REQUEST COUNT MOV (SP)+,R3 ;RETRIEVE ADDRESS OF I/O STATUS BLOCK AD CMPB -10(R3),#3 ;IS FUNCTION QIO AND WAIT? BNE 25$ ;IF NE NO MOV R0,-(SP) ;SAVE PACKET ADDRESS MOVB 2(SP),R0 ;PICK UP EVENT FLAG NUMBER BEQ 24$ ;IF EQ NONE SPECIFIED CALL $CEFI ;CONVERT FLAG TO MASK AND ADDRESS CALL $DRWFS ;PUT TASK IN WAIT STATE .IF DF G$$GEF INC @$GEFPT ;KEEP GRP GLOBALS AROUND FOR WAITFOR TEST INCB @$GFTCB ;INC GRP GBL USE COUNT FOR TASK .ENDC ; DF G$$GEF 24$: MOV (SP)+,R0 ;RESTORE PACKET ADDRESS 25$: MOV R0,R4 ;COPY PACKET ADDRESS TST (R4)+ ;POINT TO SECOND WORD IN PACKET MOVB T.PRI(R5),(R4)+ ;PRIORITY IS THAT OF ISSUING TASK MOVB (SP)+,(R4)+ ;INSERT EVENT FLAG NUMBER MOV R5,(R4)+ ;INSERT TCB ADDRESS MOV (SP)+,(R4)+ ;INSERT POINTER TO SECOND LUN WORD MOV (SP)+,R5 ;RETRIEVE UCB ADDRESS MOV R5,(R4)+ ;INSERT UCB ADDRESS MOV (SP)+,(R4) ;INSERT I/O FUNCTION CODE CLR -(SP) ;SET FLAG TO QUEUE TO DRIVER (NE 0=ACP) MOV R0,-(SP) ;SAVE ADDRESS OF I/O PACKET CLR -(SP) ;CLEAR ADDRESS OF SECONDARY CONTROL BLOC MOV SP,$TEMP0 ;MARK STACK ADDRESS MOV (R4)+,-(SP) ;SAVE I/O FUNCTION CODE CLR R1 ;ASSUME NO I/O STATUS BLOCK SPECIFIED CLR R2 ;ASSUME NO I/O STATUS BLOCK SPECIFIED MOV (R3)+,R0 ;GET ADDRESS OF I/O STATUS BLOCK BEQ 30$ ;IF EQ NONE SPECIFIED CALL $RELOC ;RELOCATE I/O STATUS BLOCK ADDRESS 30$: MOV R0,(R4)+ ;INSERT VIRTUAL ADDRESS OF I/O STATUS BL MOV R1,(R4)+ ;INSERT RELOCATION BIAS MOV R2,(R4)+ ;INSERT DISPLACEMENT ADDRESS .IF DF S$$LIB MOV (R3)+,R2 ;GET AST SERVICE ROUTINE ADDRESS CALL $CALTA ;CALCULATE ADDRESS TO STORE MOV R2,(R4)+ ;STORE PROPER AST ADDRESS .IFF MOV (R3)+,(R4)+ ;INSERT AST SERVICE ROUTINE ADDRESS .ENDC MOV (SP),R2 ;RETRIEVE I/O FUNCTION CODE CLRB R2 ;CLEAR MODIFIER FLAGS SWAB R2 ;SWAP FUNCTION CODE INTO RIGHT BYTE BNE 33$ ;IF NOT ZERO - OK JMP FCKIL ;KILL I/O FUNCTION 33$: ;REFERENCE LABEL .IF DF M$$MUP TST U.CW1(R5) ;IS THIS MOUNTABLE DEVICE? BMI 35$ ;BRANCH IF YES -- ACCESS VALIDATED LATER MOV U.OWN(R5),R0 ;IS THE DEVICE OWNED? BEQ 35$ ;IF EQ NO BITB #US.PUB,U.ST2(R5) ;PUBLIC ACCESS ALLOWED? BNE 35$ ;IF NE YES MOV $TKTCB,R1 ;POINT TO CURRENT TASK'S TCB CMP T.UCB(R1),R0 ;DEVICE OWNED BY CURRENT TASK? BEQ 35$ ;IF EQ YES BIT #T3.PRV,T.ST3(R1) ;CURRENT TASK PRIVILEGED? BNE 35$ ;IF NE YES JMP IEPRI ;ELSE PRIVILEGE VIOLATION 35$: ;ACCESS ALLOWED .ENDC CMP R2,#31. ;FUNCTION CODE IN RANGE? BHI $IEIFC ;IF HI NO MOV (R5),R1 ;GET ADDRESS OF DEVICE DCB ADD #D.MSK,R1 ;ASSUME FUNCTION CODE IN 0-15. RANGE CMP R2,#15. ;0-15. FUNCTION CODE? BLOS 40$ ;IF LOS YES ADD #10,R1 ;POINT TO SECOND MASK SET SUB #16.,R2 ;REDUCE FUNCTION CODE 40$: ASL R2 ;CONVERT TO WORD INDEX MOV $BTMSK(R2),R2 ;GET FUNCTION MASK WORD BIT R2,(R1)+ ;IS THIS A LEGAL FUNCTION? BEQ $IEIFC ;IF EQ NO BITB #US.OFL!US.PDF,U.ST2(R5) ;DEV. OFFLINE OR PRIV. DIAG.? BEQ 45$ ;IF EQ NO -- GO AHEAD AND USE IT BITB #US.OFL,U.ST2(R5) ;IS UNIT REALLY OFFLINE BEQ 42$ ;IF EQ NO JMP IEOFL ;UNIT IS OFFLINE 42$: MOV $TKTCB,-(SP) ;CHECK TO SEE IF TASK IS PRIV. ADD #T.ST3,(SP) ;POINT TO STATUS WORD IN TCB BIT #T3.PRV,@(SP)+ ;IS CURRENT TASK PRIVILEGED? BNE 452$ ;IF NE YES JMP IEOFL ;OFFLINE ERROR 452$: BIT #IQ.UMD,(SP) ;IS THI DIAGNOSTIC FUNCTION? BNE 453$ ;IF NE YES JMP IEOFL ;OFFLINE ERROR 453$: 45$: BIT R2,(R1)+ ;IS THIS FUNCTION A CONTROL FUNCTION BEQ 454$ ;IF EQ NO JMP FCCTL ;CONTROL FUNCTION 454$: BIT R2,(R1)+ ;IS FUNCTION NOP'ED? BEQ 455$ ;IF EQ, NO JMP ISSUC ;IF NE YES 455$: TST U.CW1(R5) ;MOUNTABLE DEVICE? BPL 80$ ;IF PL NO MOVB U.STS(R5),R0 ;GET STATUS BYTE FOR TESTS BELOW .IF DF R$$AMD BIT R2,(R1) ;ACP FUNCTION ? BEQ 46$ ;IF EQ NO CMP #IO.APV,(SP) ;MOUNT OR DISMOUNT QIO ? BEQ 48$ ;IF EQ YES, DOESN'T HAVE TO ;BE MOUNTED .ENDC ; R$$AMD ; ; ON REMOTE SYSTEMS, IF DEVICE IS ONE OF OUR GENERIC TYPES, THEY WILL NEVER ; BE MOUNTED. BYPASS ALL CHECKS HERE. WE STILL NEED TO PROCESS OVERLAYS ; .IF DF C$$RMT ;REMOTE HOST SUPPORT BIT #HF.RMT,$HFMSK ;TURNED ON? BEQ 46$ ;IF EQ NO CMP (R5),$XXLOW ;DCB LOWER THAN GENERICS? BLO 46$ ;IF LO YES CMP (R5),$XXHGH ;HIGHER THAN GENERICS? BHI 46$ ;IF LOS NO, ALLOW I/O CMP #IO.LOV,(SP) ;LOAD OVERLAY FUNCTION? BEQ FCLOV ;IF EQ YES CMP #IO.LDO,(SP) ;LOAD D-SPACE OVERLAY FUNCTION? BEQ FCLOV ;IF EQ YES BR FCTRN ;ALLOW TRANSFER .ENDC ;C$$RMT 46$: BITB #US.MNT!US.FOR,R0 ;VOLUME MOUNTED AND NOT FOREIGN ? BNE 60$ ;IF NE NOT MOUNTED OR FOREIGN BIT R2,(R1) ;ACP FUNCTION? BEQ 70$ ;IF EQ NO 48$: MOVB 1(SP),R2 ;RETRIEVE I/O FUNCTION CODE SUB #10,R2 ;NORMALIZE FOR POLISH DISPATCH BLT 50$ ;IF LT TABLE INCONSISTANCY ASL R2 ;CONVERT TO WORD INDEX MOV R5,-(SP) ;SAVE UCB ADDRESS FOR POLISH ROUTINES MOV R5,R0 ; MOV I.LN2-I.PRM(R4),R1 ;SAVE ADDRESS OF SECOND LUN WORD MOV R1,-(SP) ;FOR POLISH ROUTINES MOV $FCDSP(R2),R5 ;GET ADDRESS OF POLISH VECTOR JMP @(R5)+ ;EXECUTE POLISH ROUTINE ; ; REGISTERS AT POLISH DISPATCH ; ; R0 - UCB ; R1 - ADDRESS 2ND LUN WORD ; R2 - NORMALIZED FCTN CODE ; R3 - POINTER TO PARAMETERS, INITIALLY -> PARAMETER 1 ; R4 - POINTER INTO I/O PACKET, INITIALLY -> I.PRM ; ; SP-> 2ND LUN WORD ADDRESS ; UCB ADDRESS ; FUNCTION CODE ; $TEMP0->SECONDARY CONTROL BLOCK ADDRESS (OR 0) ; I/O PACKET ADDRESS ; QUEUE FLAG (0=DRIVER; NE=ACP) ; ; TASK HEADER IS ASSUMED TO BE MAPPED FOR ALL OF THE THREADED CODE ROUTINES ; ; ; DEVICE TABLE MASK WORD INCONSISTANCY ; 50$: BGCK$A BF.QIO,BE.IDC,FATAL ;DEVICE TABLE MASK WORD INCONSISTANCY ; ; DEVICE NOT MOUNTED OR MOUNTED AS FOREIGN ; 60$: BITB #US.MNT,R0 ;DEVICE NOT MOUNTED OR MOUNTED FOREIGN? BEQ 65$ ;BRANCH IF MOUNTED FOREIGN ; DEVICE NOT MOUNTED ; ALLOW TRANSFER FUNCTION IF ; THE LOADR TASK IS DOING LOGICAL I/O IN ; VIRGIN SYSTEMS WITH THE DISK NOT MOUNTED. ; ; ACP FUNCTIONS ARE ILLEGAL ; BITB #US.VV,R0 ;VOLUME VALID SET? BEQ 75$ ;IF EQ NO BIT R2,(R1) ;ACP FUNCTION? BNE 75$ ;IF NE YES BR FCTRN ;ALLOW TRANSFER ; ; MOUNTED FOREIGN ; CHECK VOLUME MOUNTED TO THIS USER ; IF ACP FUNCTION: ; ERROR IF NO ACP ; INCREMENT VOLUME TRANSACTION COUNT ; COPY PARAMETERS 1-6 (NO POLISH IF FOREIGN) ; QUEUE TO ACP UNLESS UC.QUE ALSO SET (U.CTL) ; IF TRANSFER FUNCTION: ; ADDRESS CHECK AND RELOCATE BUFFER ADDRESS IN PARM 1 ; MAP ADDRESS TO 18/22 BIT PHYSICAL ADDRESS ; COPY PARAMETERS 2-6 ; QUEUE TO DRIVER ; 65$: ; .IF DF M$$MUP CALL CXMOU ;CHECK VOLUME MOUNTED BY THIS USER BCS 75$ ;ERROR .ENDC BIT R2,(R1) ;ACP FUNCTION? BEQ FCTRN ;NOT ACP-TRANSFER TST U.ACP(R5) ;MOUNTED WITH AN ACP? BEQ 75$ ;IF EQ NO INC 6(SP) ;SET FLAG TO QUEUE TO ACP MOV U.VCB(R5),R1 ;GET VCB ADDR BEQ FCXOP ;BR IF NO VCB INC (R1) ;INCR VOL TRANS COUNT BR FCXOP ;INSERT PARAMETERS 1-6 ; ; FUNCTION IS AN ILLEGAL FUNCTION-DECLARE ILLEGAL FUNCTION CODE STATUS ; $IEIFC::MOV #IE.IFC&377,R4 ;SET ILLEGAL FUNCTION JMP IECMN ; ; DEVICE MOUNTED AND NOT FOREIGN BUT NOT ACP FUNCTION ; 70$: CMP #IO.LOV,(SP) ;LOAD OVERLAY FUNCTION? BEQ FCLOV ;IF EQ YES CMP #IO.LDO,(SP) ;LOAD D-SPACE OVERLAY FUNCTION? BEQ FCLOV ;IF EQ YES MOV $TKTCB,R0 ;GET ADDRESS OF TCB OF CURRENT TASK BIT #T3.PRV,T.ST3(R0) ;TASK PRIVILEGED? BEQ 75$ ;IF EQ NO, PRIVILEGE VIOLATION .IF NDF R$$PRO CMPB #IO.WLB/400,1(SP) ;IS IT A WRITE LOGICAL BLOCK FUNCTION ? BNE FCTRN ;IF NE NO, OK TO ISSUE BITB #US.LAB,U.STS(R5) ;ANSI MAGTAPE MOUNTED ? BNE FCTRN ;IF NE YES, OK TO ISSUE MOV 6(R3),-(SP) ;SAVE FIRST HALF OF BLOCK NUMBER BIS 10(R3),(SP)+ ;BOTH HALVES ZERO ? .ENDC ; DF R$$PRO BNE FCTRN ;IF NE NOT LBN 0, OK TO ISSUE CMP $RCTPT,R0 ;IS THE CURRENT TASK RCT? BEQ FCTRN ;IF EQ, YES, ALLOW WRITE TO LBN 0 75$: JMP IEPRI ;PRIVILEGE VIOLATION ; ; INTERMEDIATE TO FCKIL ; 76$: BR FCKIL ;BRANCH TO HANDLE KILL I/O ; ; DEVICE IS NOT MOUNTABLE ; 80$: BIT R2,(R1) ;ACP FUNCTION? BEQ FCTRN ;IF EQ NO ; ; FUNCTION IS A FILE STRUCTURE FUNCTION FOR A NONFILE STRUCTURED DEVICE. ; INITION THIS MUST BE A READ OR WRITE VIRUTAL SINCE ALL OTHER FUNCTIONS ; HAVE BEEN EITHER ILLEGAL OR NOP'ED. MAP FUNCTION TO IT LOGICAL COUNTER ; MOV #IO.WLB,I.FCN-I.PRM(R4) ;ASSUME FUNCTION IS WRITE VIRTUAL CMPB #IO.WVB/400,1(SP) ;WRITE VIRTUAL FUNCTION? BEQ FCTRN ;IF EQ YES MOV #IO.RLB,I.FCN-I.PRM(R4) ;SET FUNCTION TO READ LOGICAL BLOCK BR FCTRN ;GO TRANSLATE BUFFER ADDRESS .DSABL LSB ; ; FUNCTION IS A TRANSFER FUNCTION-ADDRESS CHECK AND MAP TRANSFER ; FCLOV: ;REFERENCE LABEL .IF DF U$$DAS!A$$CNT CALL FACHL ;ADDRESS CHECK LOAD OVERLAY IN USER I BR FCTR1 ;ENTER COMMON CODE .ENDC ; DF U$$DAS!A$$CNT FCTRN: CALL FACHK ;PERFORM ADDRESS CHECK FCTR1: CALL $MPPHY ;MAP TO 18/22 BIT PHYS ADDRESS CALL FCXR1 ;INSERT RELOC DISP & BIAS; & PARM 2-6 BR FCXTR ; ; ; FUNCTION IS A KILL I/O FUNCTION-FLUSH I/O QUEUE OF TASK REQUESTS ; FCKIL: MOV (SP),$TEMP2 ;SAVE I/O FUNCTION CODE CALL $IOKL2 ;FLUSH I/O QUEUE ; ; FUNCTION IS A NOP'ED FUNCTION-DECLARE SUCCESSFUL COMPLETION STATUS ; ISSUC: MOV #IS.SUC&377,R4 ;SET SUCCESSFUL COMPLETION CODE IECM1: JMP IECOM ; ; ; SPECIFIED DEVICE IS OFFLINE ; IEOFL: MOV #IE.OFL&377,R4 ;SET DEVICE OFFLINE STATUS BR IECM1 ; ; ; ; FUNCTION IS A CONTROL FUNCTION-COPY REMAINDER OF DPB ; FCCTL: TST U.CW1(R5) ;MOUNTABLE DEVICE? BPL 10$ ;IF PL NO MOV $TKTCB,R0 ;POINT TO CURRENT TASK TCB BITB #US.MNT!US.FOR,U.STS(R5) ;DEVICE MOUNTED AND NOT FOREIGN ? BNE 5$ ;IF NE NO BITB #US.LAB,U.STS(R5);ANSI MAGTAPE ? BEQ 6$ ;IF EQ NO 4$: BIT #T3.PRV,T.ST3(R0) ;ISSUING TASK PRIVILEGED ? BNE 10$ ;IF NE YES - ISSUE FUNCTION 45$: JMP IEPRI ;NO - PRIVILEGE VIOLATION 5$: ;REFERENCE LABEL ; ; IF THE EXEC HANDLES VV VS CTL FUNCTIONS, IT GOES HERE ; 6$: TST U.OWN(R5) ;DEVICE ALLOCATED ? BEQ 10$ ;IF EQ NO CMP U.OWN(R5),T.UCB(R0) ;DEVICE ALLOCATED TO THIS USER ? BNE 4$ ;IF NE NO, CHECK PRIVILEGED. 10$: ;REFERENCE SYMBOL FCXOP: CALL FCXP1 ;INSERT PARAMETERS 1-6 FCXTR: ;REFERENCE SYMBOL BITB #IQ.UMD,(SP) ;IS THIS A DIAGNOSTIC FUNCTION? BEQ 10$ ;IF EQ NO BIT #DV.UMD,U.CW1(R5) ;DOES DEVICE SUPPORT DIAGNOSTICS? BEQ 10$ ;IF EQ NO CMPB 1(SP),#IO.ATT/256. ;IS THIS AN ATTACH FUNCTION? BEQ 10$ ;IF EQ YES, SKIP RELOCATION CMPB 1(SP),#IO.DET/256. ;IS THIS A DETACH FUNCTION? BEQ 10$ ;IF EQ YES BITB #US.UMD,U.ST2(R5) ;IS DEVICE ATTACHED FOR DIAGNOSTICS? BEQ IEPRI ;IF EQ NO, PRIVILEGE VIOLATION MOV (R4),R0 ;PICK UP REGISTER BUFFER ADDRESS MOV #40.*2,R1 ;PICK UP MAX LENGTH CALL $CKBFW ;CHECK AND LOCK DIAGNOSTIC BUFFER BCS IESPC ;IF CS ADDRESS CHECK FAILED CALL $RELOC ;RELOCATE REGISTER BUFFER MOV R1,(R4)+ ;STORE KISAR6 BIAS MOV R2,(R4) ;STORE DISPLACEMENT 10$: MOV (SP)+,R1 ;RESTORE FUNCTION CODE CMP #IO.LOV,R1 ;IS THIS AN I-SPACE LOAD OVERLAY BEQ 15$ ;IF EQ YES CMP #IO.LDO,R1 ;IS THIS A D-SPACE LOAD OVERLAY BNE FCXIT ;IN NE NO 15$: TST U.CW1(R5) ;MOUNTABLE DEVICE? BPL FCXIT ;IF PL NO MOV $TKTCB,R3 ;GET ADDRESS OF TCB OF CURRENT TASK .IF DF C$$RTK ;IF REMOTE TASK SUPPORT BIT #F5.RTK,$FMSK5 ;REMOTE TASK SUPPORT TURNED ON? BEQ 20$ ;IF EQ NO MOV T.LDV(R3),R0 ;GET UCB ADDRESS CALL @#$MPLND ;FOLLOW REDIRECT POINTERS CMP (R0),$XXLOW ;IS THIS ONE OF OUR GENERIC DCBS BLO 20$ ;IF LO NO CMP (R0),$XXHGH ;CHECK FOR TOO HIGH BHI 20$ ;IF HIGHER, NOT GENERIC BR FCXIT ;BYPASS MOUNTED CHECK AND LBN CONVERSION 20$: .ENDC ; C$$RTK BIT #T4.LDD,T.ST4(R3) ;WAS LOAD DEVICE DISMOUNTED ? BNE IEPRI ;IF NE YES, REJECT I/O ; ; IF THIS IS A FIXED TASK WITHOUT A TASK IMAGE SAVE SET T.LBN TO ZERO. ; NO LEGIT TASK SHOULD HAVE A ZERO T.LBN BECAUSE BLOCK ZERO IS RESERVED ; FOR THE BOOT BLOCK. SUCH A TASK (FIXED WITH NO IMAGE) SHOULD NOT ; PERFORM DISK OVERLAY LOAD REQUESTS. ; .IF DF F$$NIM MOVB T.LBN(R3),R0 ;GET HIGH BYTE OF LBN BIS T.LBN+1(R3),R0 ;MERGE IN LOW BYTE, TEST FOR ALL ZERO BEQ IEPRI ;IF EQ YES, REJECT I/O .ENDC ; DF F$$NIM MOV T.LDV(R3),R0 ;GET UCB ADDRESS OF LOAD DEVICE ;+ ; ** W A R N I N G ** ; ; SPM HOOKPOINT NUMBER 25. ; ; DO NOT CHANGE THE INSTRUCTION FOLLOWING ; LABEL WITHOUT CHECKING SPM ;- $SPH25==. ;SPM CHANGES THE INSTRUCTION AT ;THE LOCATION OF THIS LABEL CALL @#$MPLND ;MAP TO ACTUAL UCB ADDRESS CMP R0,R5 ;LOAD DEVICE UCB MATCH SPECIFIED UCB? BNE IEOVR ;IF NE NO ADD T.LBN+1(R3),-(R4) ;ADD IN LOW PART OF TASK LOGICAL ADC -(R4) ;BLOCK NUMBER MOVB T.LBN(R3),R0 ;GET HIGH BYTE OF TASK LOGICAL BLOCK NUM .IF NDF U$$DAS ADD R0,(R4) ;ADD IN HIGH PART .IFF ; NDF U$$DAS ADD R0,(R4)+ ;ADD IN HIGH PART SUB T.ISIZ(R3),(R4) ;ADJUST TO START OF SBC -(R4) ;REAL D-SPACE .ENDC ; NDF U$$DAS FCXIT: TST (SP)+ ;CLEAN STACK MOV (SP)+,R1 ;RETRIEVE ADDRESS OF I/O PACKET TST (SP)+ ;QUEUE TO DRIVER BEQ DRQRQ ;IF EQ YES, IF NE Q ACP BITB #UC.QUE,U.CTL(R5) ;IF SET QUEUE TO DRIVER BNE DRQRQ ;EVEN IF ACP FUNCTION ;+ ; ** W A R N I N G ** ; ; SPM HOOKPOINT NUMBER 20. ; ; DO NOT CHANGE THE INSTRUCTION FOLLOWING ; LABEL WITHOUT CHECKING SPM ;- $SPH20==. ;SPM CHANGES THE INSTRUCTION AT ;THE LOCATION OF THIS LABEL MOV U.ACP(R5),R0 ; .IF DF R$$AMD ; ; IF THE VOLUME IS NOT MOUNTED OR MOUNTED FOREIGN, THEN U.ACP POINTER ; IS STILL ZERO. FOR THESE CASES, QUEUE IO.APV TO THE DEFAULT ACP ; BNE 10$ ;IF NE DEVICE ALREADY HAS AN ACP MOV $ACPTK,R0 ;GET DEFAULT FILES-11 ACP POINTER 10$: .ENDC ; DF R$$AMD CALLR $EXRQP ;INSURE FILE SYSTEM ACTIVE ; ; DESCRIPTION OF QUEUING AND INTERLOCKING INTERFACES ; FOR MOUNTABLE DEVICES ; ; I. NOT MOUNTED - ALLOW XFER FCTNS IF 'VOLUME VALID' SET ; (NEEDED FOR STARTUP). ACP FCTNS ARE ILLEGAL. ; ADDRESS CHECK & MAP BUFFER ADDRESS IN ; PARAMETER 1. ; QUEUE TO DRIVER. ; ; II. MOUNTED ; A. ALL CASES - IF 'UC.QUE' SET IN 'U.CTL' THEN QUEUE ; TO DRIVER. (NECESSARY TO SUPPORT EXISTING ; DRIVERS THAT ARE REALLY LIKE ACP'S). ; ; B. MOUNTED FOREIGN ; 1. XFER FCTN - ADDRESS CHECK AND MAP ; BUFFER ADDRESS IN PARAMETER 1. COPY ; PARAMETERS 2-6. QUEUE TO DRIVER. ; 2. ACP FCTN - ERROR IF NO ACP. COPY PARAMETERS ; 1-6. NO POLISH ROUTINE PROCESSING. ; INCREMENT VOLUME TRANSACTION COUNT. ; QUEUE TO ACP. ; ; C. MOUNTED NOT FOREIGN ; 1. XFER FCTN - EITHER OVERLAY OR PRIVILEGED ; TASK I/O. ADDRESS CHECK AND MAP ; BUFFER ADDRESS IN PARAMETER 1. COPY ; PARAMETERS 2-6. QUEUE TO DRIVER. ; 2. DECNET ACP - I/O FUNCTION CODES ARE DISJOINT ; FROM FILES ACPS' FUNCTION CODES. POLISH ; ROUTINE PROCESSING. QUEUED TO DRIVER ; BECAUSE 'UC.QUE' SET. ; 3. ANSI MAGTAPE (MTAACP) - SAME FUNCTION ; CODES AS DISK FILE ACP (F11ACP) BUT ; NOT ALL ARE ALLOWED. POLISH ROUTINE ; PROCESSING. ALL OPERATIONS QUEUED TO ; MTAACP. NO BLOCK LOCKING. ACCESS/DEACCES ; INTERLOCK BUT NO WINDOW TURN PENDING ; COUNT BECAUSE EVERYTHING QUEUED TO ACP. ; INCREMENT VOLUME TRANSCACTION COUNT. ; 4. FILES-11 DISK ACP (F11ACP) - POLISH ROUTINE ; PROCESSING. TABLE BELOW DESCRIBES QUEUIN ; AND INTERLOCKING. LEGEND: A=QUEUE TO ACP ; D=QUEUE TO DRIVER; I=INTERLOCK LUN; ; P=INCREMENT WINDOW TURN PENDING COUNT. ; VOLUME TRANSACTION COUNT INCREMENTED. ; SEE COMMENT LOCATED NEAR CKRAC AND CKWAC ; FOR DESCRIPTION OF WINDOW TURN PENDING ; COUNT ALGORITHM. ; DRQRQ: ;REFERENCE LABEL ; ; CHECK SOFTWARE WRITE LOCK BEFORE GOING TO $DRQRQ ; BIT #DV.MSD,U.CW1(R5) ;MASS STORAGE DEVICE? BEQ 20$ ;IF EQ NO BIT #DV.SWL,U.CW1(R5) ;SOFTWARE WRITE LOCKED? BEQ 20$ ;IF EQ NO CMPB #IO.RLB/256.,I.FCN+1(R1) ;READ LOGICAL FUNCTION? BEQ 20$ ;IF EQ YES CMPB #IO.WLB/256.,I.FCN+1(R1) ;WRITE LOGICAL FUNCTION? BEQ IEWLK ;IF EQ YES MOV #$WLKTB,R4 ;POINT TO TABLE (IN QITBL) MOV I.FCN(R1),R0 ;GET FUNCTION CODES BIC #7,R0 ;GET RID OF MODIFIERS 10$: CMP (R4)+,R0 ;IS THIS THE FUNCTION CODE? BEQ IEWLK ;IF EQ YES TST (R4) ;END OF TABLE? BNE 10$ ;IF NE NO 20$: JMP $DRQRQ ;QUEUE I/O REQUEST ; ; WRITE ATTEMPTED TO WRITE LOCKED UNIT ; IEWLK: MOV #IE.WLK&377,R4 ;SET WRITE LOCK ERROR BR IECMN ; ; ; ILLEGAL BUFFER ADDRESS SPECIFIED-DECLARE ILLEGAL BUFFER STATUS ; I2SPC: CLR -(R4) ;ERASE LAST ATTRIBUTE NUMBER IESPC: MOV #IE.SPC&377,R4 ;SET ILLEGAL BUFFER CODE IECOM: BR IECMN ; ; ; ILLEGAL LOAD OVERLAY UCB-DECLARE ILLEGAL LOAD OVERLAY FUNCTION STATUS ; IEOVR: MOV #IE.OVR&377,R4 ;SET ILLEGAL LOAD OVERLAY CODE BR IECMN ; ; ; ILLEGAL BYTE COUNT OR ALIGNMENT-DECLARE ODD BYTE STATUS ; IEBYT: MOV #IE.BYT&377,R4 ;SET ODD BYTE STATUS BR IECMN ; ; ; NO BUFFER SPACE AVAILABLE-SET NO BUFFER AVAILABLE STATUS ; IENOD: MOV #IE.NOD&377,R4 ;SET NO BUFFER AVAILABLE CODE BR IECMN ; ; ; BAD PARAMETER-SET BAD PARAMETER STATUS ; IEBAD: MOV #IE.BAD&377,R4 ;SET BAD PARAMETER CODE BR IECMN ; ; ; PRIVILEGE VIOLATION-SET PRIVILEGE VIOLATION STATUS ; IEPRI: MOV #IE.PRI&377,R4 ;SET PRIVILEGE VIOLATION CODE BR IECMN ; ; ; FILE ALREADY ACCESSED ON LUN-SET FILE ALREADY ACCESSED STATSU ; IEALN: MOV #IE.ALN&377,R4 ;SET FILE ALREADY ACCESSED CODE BR IECMN ; ; ; NO FILE ACCESSED ON LUN-SET NO FILE ACCESSED STATUS ; IENLN: MOV #IE.NLN&377,R4 ;SET NO FILE ACCESSED STATUS .IF DF,R$$LKL BR IECOM ; ; ; EXPLICIT UNLOCK PERFORMED OR BLOCK LOCKING ERROR ; STATUS IN R0 ; IELCK: MOV R0,R4 ;STATUS IN R0 .ENDC ; ; COMMON ERROR EXIT ; IECMN: MOV $TEMP0,SP ;RESET STACK POINTER MOV (SP)+,R0 ;RETRIEVE ADDRESS OF SECONDARY CONTROL B BEQ 10$ ;IF EQ NONE CALL $DEATR ;DEALLOCATE SECONDARY CONTROL BLOCK 10$: .IF DF C$$RTK ;REMOTE TASKS BIT #F5.RTK,$FMSK5 ;REMOTE TASKS TURNED ON? BEQ 20$ ;IF EQ NO MOV (SP),R3 ;GET ADDRESS OF I/O PACKET CMPB I.FCN+1(R3),#IO.KIL/256. ;IS THIS I/O KILL? BNE 20$ ;IF NE NO MOV $CPPKT,R0 ;GET ADDRESS OF PACKET BEQ 20$ ;IF EQ, NONE CALL $CPDEA ;DEALLOCATE IT .ENDC ;C$$RTK 20$: MOV R4,R0 ;SET FINAL I/O STATUS CLR R1 ;CLEAR SECOND I/O STATUS WORD MOV (SP)+,R3 ;RETRIEVE ADDRESS OF I/O PACKET TST (SP)+ ;CLEAN STACK MOV I.UCB(R3),R5 ;RETRIEVE UCB ADDRESS CALLR $IOFIN ;FINISH OFF I/O OPERATION ; ; BUILD AN I/O PACKET ; $BDPKT::INC 12(SP) ;QUEUE PACKET TO ACP NOT DRIVER MOV #2*2,R1 ;SET LENGTH OF FILE ID BLOCK CALL OPPRM ;INSERT OPTIONAL FILE ID BLOCK BEQ ATRBK ;IF EQ NO PARAMETER BLOCK SPECIFIED ; ; BUILD ATTRIBUTE POINTER BLOCK ; ATRBK: MOV (R3)+,(R4)+ ;ATTRIBUTE DESCRIPTOR BLOCK SPECIFIED? BEQ MOVE3 ;IF EQ NO MOV R3,-(SP) ;SAVE ADDRESS OF NEXT DPB WORD MOV #I.ATRL,R1 ;SET LENGTH OF SECONDARY CONTROL BLOCK CALL $ALOCB ;ALLOCATE SECONDARY CONTROL BLOCK BCS IENOD ;IF CS NO STORAGE AVAILABLE MOV R0,@$TEMP0 ;SAVE ADDRESS OF SECONDARY CONTROL BLOCK CLR (R0) ;INITIALIZE NUMBER OF ATTRIBUTES MOV KISAR6,-(SP) ;SAVE CURRENT MAPPING MOV -(R4),R3 ;RETRIEVE ADDRESS OF ATTRIBUTE DESCRIPTO MOV R0,(R4)+ ;SET POINTER TO SECONDARY CONTROL BLOCK MOV R4,-(SP) ;SAVE ADDRESS OF NEXT WORD IN I/O PACKET MOV R0,R4 ;SET ADDRESS OF FIRST ATTRIBUTE POINTER MOV #6,-(SP) ;SET MAXIMUM NUMBER OF ATTRIBUTE POINTER 10$: MOV R3,R0 ;SET ADDRESS OF NEXT ATTRIBUTE DESCRIPTO MOV #4,R1 ;SET SIZE OF ATTRIBUTE DESCRIPTOR CALL $ACHCK ;ADDRESS CHECK ATTRIBUTE DESCRIPTOR BCS IESPC ;IF CS ADDRESS CHECK FAILURE CALL $RELOM ;RELOCATE AND MAP ATTRIBUTE DESCRIPTOR ADD #4,R3 ;POINT TO NEXT ATTRIBUTE DESCRIPTOR MOVB (R0)+,(R4)+ ;INSERT ATTRIBUTE NUMBER BEQ 20$ ;IF EQ END OF ATTRIBUTE DESCRIPTOR BLOCK CLR R1 ;PICKUP SIZE OF ATTRIBUTE BLOCK BISB (R0)+,R1 ; MOVB R1,(R4)+ ;INSERT LENGTH OF ATTRIBUTE BLOCK BNE 15$ ;IF NE LENGTH OKAY MOV #256.*2,R1 ;SET LENGTH FOR ZERO CASE 15$: MOV (R0),R0 ;GET ADDRESS OF ATTRIBUTE BLOCK .IF DF X$$HDR MOV KISAR6,-(SP) ;SAVE CURRENT MAPPING MOV 6(SP),KISAR6 ;MAP TASK HEADER .ENDC CALL IOBUF ;ADDR CHECK AND INC I/O COUNT .IF DF X$$HDR MOV (SP)+,KISAR6 ;RESTORE MAPPING TO ATTRIBUTE BLOCK .ENDC BCS I2SPC ;IF CS ADDRESS CHECK FAILURE MOV R1,(R4)+ ;SAVE ADDRESS OF ATTACHMENT DESCRIPTOR CALL $RELOC ;RELOCATE ATTRIBUTE BLOCK ADDRESS MOV R1,(R4)+ ;INSERT RELOCATION BIAS MOV R2,(R4)+ ;INSERT ATTRIBUTE BLOCK ADDRESS DEC (SP) ;ANY MORE SPACE IN POINTER BLOCK? BGT 10$ ;IF GT YES 20$: TST (SP)+ ;CLEAN STACK MOV (SP)+,R4 ;RETRIEVE ADDRESS OF NEXT WORD IN I/O PA MOV (SP)+,KISAR6 ;RESTORE CURRENT MAPPING MOV (SP)+,R3 ;RETRIEVE ADDRESS OF NEXT WORD IN DPB ; ; MOVE EXTEND AND ACCESS CONTROL WORDS INTO I/O PACKET ; MOVE3: MOV (R3)+,(R4)+ ;INSERT EXTEND CONTROL WORDS MOV (R3)+,(R4)+ ; MOV (R3)+,(R4)+ ;INSERT ACCESS CONTROL WORD ; ; INSERT OPTIONAL FILENAME BLOCK ; FILNM: MOV #13.*2,R1 ;SET LENGTH OF FILENAME BLOCK CALL OPPRM ;INSERT OPTIONAL FILENAME BLOCK BEQ 10$ ;IF EQ NO FILENAME BLOCK SPECIFIED 10$: JMP @(R5)+ ; ; ; INTERPRET REQUIRED BLOCK ADDRESS ; .ENABL LSB RQPRM: MOV SP,R2 ;SET REQUIRED PARAMETER FLAG BR 10$ ; ; ; INTERPRET OPTIONAL BLOCK ADDRESS ; OPPRM: CLR R2 ;CLEAR REQUIRED PARAMETER FLAG 10$: MOV (R3)+,R0 ;GET ADDRESS OF CONTROL BLOCK BEQ 20$ ;IF EQ NONE SPECIFIED CALL $CKBFW ;CHECK AND LOCK USER BUFFER BCC 15$ ;IF CC, ADDRESS CHECK OKAY JMP IESPC ;OTHERWISE FINISH WITH ERROR 15$: MOV R1,-(SP) ;SAVE ATT DESCR ADDR CALL $RELOC ;RELOCATE BUFFER ADDRESS MOV R1,(R4)+ ;INSERT RELOCATION BIAS MOV R2,(R4)+ ;INSERT BLOCK ADDRESS MOV (SP)+,R1 ;RESTORE ATT DESCR ADDR BR 30$ ; 20$: MOV R2,(R4)+ ;PARAMETER REQUIRED? BEQ 25$ ;IF EQ NO JMP IEBAD ;OTHERWISE FINISH WITH ERROR 25$: CLR (R4)+ ;CLEAR SECOND WORD 30$: RETURN ; .DSABL LSB ; ; FILL DISCONNECT PARAMETER BUFFER AND INTERLOCK LUN USAGE ; .IF DF M$$NET .ENABL LSB $CKDIS::MOV (R3)+,(R4)+ ;COPY FIRST PARAMETER TO I/O PACKET BR 10$ ;FINISH IN COMMON CODE ; ; CHECK CONNECT PARAMETER BUFFER ; $CKPRM::CALL FCXP1 ;COPY PARAMETERS (UNTOUCHED) JMP @(R5)+ ; $CKHDR:: ; .IF DF X$$HDR MOV U.SCB(R0),R2 ;GET SCB ADDRESS BIT #S2.XHR,S.ST2(R2) ;COMM PRODUCT SUPPORT EXTERNAL HEADERS? BNE 20$ ;IF NE YES CMP #120000,R1 ;HEADER RESIDENT IN POOL? BHIS 20$ ;IF HIS YES JMP IEBAD ;RETURN BAD PARAMETER ERROR .ENDC $CKCON:: ; 2$: MOV 2(R3),R1 ;GET LENGTH OF BUFFER IN BYTES BNE 5$ ;IF NE NON ZERO LENGTH JMP IESPC ;ZERO LENGTH 5$: CALL RQPRM ;INSERT REQUIRED PARAMETER 10$: CALL FCXP2 ;INSERT PARAMETERS 20$: JMP @(R5)+ ; .DSABL LSB .ENDC ; ; CHECK FOR VOLUME MARKED FOR DISMOUNT ; .ENABL LSB $CKDMO::BITB #US.MDM,U.STS(R0) ;VOLUME MARKED FOR DISMOUNT? BNE 15$ ;IF NE YES JMP @(R5)+ ; ; ; CHECK VOLUME MOUNTED BY THIS USER ; .IF DF M$$MUP $CKMOU:: ;REFERENCE LABEL .IF DF R$$AMD CMP #IO.APV,4(SP) ;MOUNT/DISMOUNT I/O REQUEST ? BEQ 2$ ;IF EQ YES - BYPASS MOUNT CHECK .ENDC ; DF R$$AMD MOV R5,-(SP) ;SAVE R5 MOV 4(SP),R5 ;GET UCB ADDRESS CALL CXMOU ;IS DEVICE MOUNTED BY THIS USER? BCS 15$ ;IF CS NO MOV (SP)+,R5 ;RESTORE REGISTER 2$: JMP @(R5)+ ; ; ; SUBROUTINE TO SEARCH MOUNT LIST TO SEE IF VOLUME ; REALLY MOUNTED BY THIS USER ; CXMOU: MOV R1,-(SP) ;SAVE REGISTERS MOV R2,-(SP) ; BITB #US.PUB,U.ST2(R5) ;PUBLIC DEVICE? BNE 8$ ;PUBLIC DEVICE OK MOV $TKTCB,R1 ;IS TASK PRIVILEGED? BIT #T3.PRV,T.ST3(R1) BNE 8$ ;PRIVILEGED TASK OK MOV T.UCB(R1),R1 ;GET USER TI: UCB ADDR AS ID MOV #$MOULS,R2 ;GET MOUNT LIST 5$: SEC ;ASSUME FAIL MOV (R2),R2 ;GET MOUNT LIST ENTRY BEQ 9$ ;NONE=DONE=FAIL CMPB #MT.MLS,M.TYPE(R2) ;RIGHT TYPE OF ENTRY? BNE 5$ ;BR NOT MOUNT ENTRY CMP M.DEV(R2),R5 ;SAME DEVICE UCB? BNE 5$ ;BR DIFFERENT DEVICE CMP M.TI(R2),R1 ;SAME USER AS TI? BNE 5$ ;BR DIFFERENT USER 8$: CLC ;SUCCESS 9$: MOV (SP)+,R2 ;RESTORE REGISTERS MOV (SP)+,R1 ; RETURN .ENDC ; ; CHECK FOR READ ACCESS PRIVILEGES AND EXIT TO TRANSFER FUNCTION ; $CKRAC::MOV #WI.RDV,R2 ;SET READ ACCESS MASK WORD BR 10$ ; ; ; CHECK FOR WRITE ACCESS PRIVILEGES AND EXIT TO TRANSFER FUNCTION ; $CKWAC::MOV #WI.WRV,R2 ;SET WRITE ACCESS MASK WORD 10$: BIT R2,@(R1)+ ;DESIRED ACCESS PERMITTED? BNE 20$ ;IF NE YES 15$: JMP IEPRI ;PRIVILEGE VIOLATION ; ; ADDRESS CHECK & INSERT RELOC BIAS, DISP & PARM 2-6 ; 20$: MOV R0,R5 ;GET UCB ADDRESS CALL FACHK ;PERFORM ADDRESS CHECK CALL FCXR1 ;INSERT PARAMETERS .IF DF,M$$NET CMPB #IO.WVB/400,5(SP) ;DECNET FUNCTION? BGE CKLCK ;IF GE NO MOV U.SCB(R5),R0 ;GET SCB ADDRESS BIT #S2.XHR,S.ST2(R0) ;NEW I.LN2 HANDLING SUPPORTED? BNE 50$ ;IF NE YES MOV $TKTCB,R0 ;GET TASK TCB ADDRESS MOV T.ATT(R0),R0 ;GET TASK PARTITION ATTACHMENT DESCRIPTOR INCB A.IOC-A.TCBL(R0) ;LOCK DOWN THE HEADER FOR THE I/O MOV A.PCB-A.TCBL(R0),R0 ;GET ADDRESS OF TASK REGION INCB P.IOC(R0) ;BUMP REGION'S I/O COUNT MOV 10(SP),R0 ;GET THE I/O PACKET ADDRESS BR 55$ ;JOIN COMMON CODE .ENDC ; ; DO RMS BUCKET LOCKING PROCESSING ; CKLCK: BITB #US.LAB,U.STS(R5) ;ANSI MAGTAPE BNE 30$ ;IF NE YES MOV 10(SP),R1 ;GET ADDRESS I/O PACKET .IF DF,R$$LKL CALL $LCKPR ;PERFORM LOCK PROCESSING BCC 22$ ;CS IF ERROR OR UNLOCK DONE JMP IELCK ; 22$: ;REFERENCE LABEL .ENDC CALL $MPPKT ;MAP VBN TO LBN BCS 30$ ;MAP FAILURE TST R0 ;ALL BLOCKS MAPPED?? BEQ 40$ ;IF EQ YES 30$: INC 12(SP) ;QUEUE TO ACP 40$: MOV @(SP),R0 ;GET ADDRESS OF WINDOW INCB W.IOC(R0) ;ADJUST WINDOW I/O COUNT 50$: MOV 10(SP),R0 ;GET I/O PACKET ADDRESS MOV @I.LN2(R0),I.LN2(R0) ;CHANGE I.LN2 TO IMAGE OF LUT2 INC I.LN2(R0) ;FLAG IT AS SUCH 55$: BISB #200,I.EFN(R0) ;FLAG PACKET AS VIRTUAL I/O FUNCTION TST (SP)+ ;CLEAN STACK MOV (SP)+,R5 ;RESTORE TO UCB ADDRESS TST (SP)+ ;CLEAN STACK CKJXT: JMP FCXIT ; .DSABL LSB ; ; CHECK FOR FILE ALREADY ACCESSED ON LUN ; $CKALN::TST (R1) ;FILE ACCESSED ON LUN? BEQ CKJR5 ;IF EQ NO JMP IEALN ;ERROR ; ; CHECK FOR FILE ACCESSED ON LUN ; $CKNLN::TST (R1) ;FILE ACCESSED ON LUN? BNE CKJR5 ;IF NE YES JMP IENLN ;ERROR ; ; SET UP REGISTERS FOR UNLOCK AND EXIT TO CONTROL FUNCTION ; .IF DF R$$LKL $UNLXT::TST (R4)+ ;SKIP FIRST WORD OF "ADDRESS DOUBLEWORD" MOV R0,R5 ;SETUP UCB POINTER CALL FCXP1 ;COPY PARAMETERS BR CKLCK ; .ENDC ; ; SET ACCESS/DEACCESS INTERLOCK ; $CKRLK::INC @(SP) ;SET ACCESS/DEACCESS PENDING INTERLOCK ; ; EXIT POLISH TO FUNCTION EXIT ; $CKXIT::TST (SP)+ ;REMOVE ADDRESS OF SECOND LUN WORD MOV (SP)+,R5 ;RETRIEVE UCB ADDRESS TST (SP)+ ;ADJUST STACK PTR MOV U.VCB(R5),R1 ;GET VCB ADDR BEQ CKJXT ;BR IF NO VCB INC (R1) ;INCR VOLUME TRANS COUNT BR CKJXT ;EXIT POLISH $CKPKT::MOV #$FCPKT,R5 ;JOIN COMMON ACP REQUESTS CKJR5: JMP @(R5)+ ; ; ; INCREMENT WINDOW I/O COUNT FOR MOUNTED FILES-11 DEVICES ; $CKIWN::MOV @(SP),R0 ;GET CONTENTS OF LUT2 BIC #1,R0 ;CLEAR LUN INTERLOCK, WINDOW? BEQ 10$ ;IF EQ NO INCB W.IOC(R0) ;BUMP WINDOW I/O COUNT 10$: JMP @(R5)+ ; ; ; LOCK HEADER IN MEMORY DURING ACP FUNCTION ; $CKLHD::MOV $TKTCB,R0 ;GET CURRENT TASK TCB ADDRESS MOV T.ATT(R0),R0 ;GET ATTACHMENT DESCRIPTOR INCB A.IOC-A.TCBL(R0) ;BUMP I/O COUNT FOR TASK REGION MOV A.PCB-A.TCBL(R0),R0 ;GET ADDRESS OF TASK REGION INCB P.IOC(R0) ;BUMP REGION'S I/O COUNT MOV 10(SP),R0 ;GET ADDRESS OF I/O PACKET BISB #200,I.EFN(R0) ;FLAG REQUEST AS A VIRTUAL I/O REQUEST JMP @(R5)+ ; ; ; SUBROUTINES TO COPY PARAMETERS INTO I/O PACKET ; ; INPUTS: ; FCXR1 - R1 RELOCATION BIAS ; R2 DISPLACEMENT BIAS ; R3 PARAMETER PTR ; R4 I/O PACKET PTR ; COPIES R1, R2, AND PARAMETERS 2-6 ; ; FCXP2 - R3, R4 ; COPIES PARAMETERS 2-6 ; ; FCXP1 - R3, R4 ; COPIES PARAMETERS 2-6 ; ; OUTPUTS: R3, R4 UPDATED PTR'S ; FCXR1: MOV R1,(R4)+ ;INSERT RELOCATION BIAS MOV R2,(R4)+ ;INSERT DISPLACEMENT BIAS BR FCXP2 ;COPY PARAMETRS 2-6 FCXP1: MOV (R3)+,(R4)+ ;INSERT PARAMETER 1 FCXP2: MOV (R3)+,(R4)+ ;INSERT PARAMETER 2 MOV (R3)+,(R4)+ ;INSERT PARAMETER 3 MOV (R3)+,(R4)+ ;INSERT PARAMETER 4 MOV (R3)+,(R4)+ ;INSERT PARAMETER 5 MOV (R3)+,(R4) ;INSERT PARAMETER 6 RETURN ; ; SUBROUTINE TO PERFORM ADDRESS CHECK AND MAP TRANSFER ; FACHL: .IF DF A$$CNT MOV KISAR6,-(SP) ;SAVE CURRENT EXEC MAPPING MOV $TKTCB,R0 ;GET TCB ADDRESS OF CURRENT TASK MOV T.ACN(R0),KISAR6 ;MAP TO TAB (OR OTHER BLOCK) BEQ 10$ ;IF EQ NO BLOCK CMPB #BT.TAB,@#B.TYP+140000 ;IS THIS A TAB ? BNE 10$ ;IF NE NO ADD #1,@#B.OVLY+2+140000 ;INCREMENT COUNT ADC @#B.OVLY+140000 ;SECOND HALF 10$: MOV (SP)+,KISAR6 ;RESTORE PREVIOUS MAPPING .ENDC ; DF A$$CNT .IF DF U$$DAS CMP I.FCN-I.PRM(R4),#IO.LDO ;IS THIS A D-SPACE LOAD OVERLAY BEQ FACHK ;IF EQ YES MOV #$RELUI,-(SP) ;PUSH ADDRESS OF RELOCATION ROUTINE MOV #$CKBFI,-(SP) ;AND ADDRESS OF ADDR. CHECK ROUTINE BR FACH1 ;ENTER COMMON CODE .IFTF ; DF U$$DAS FACHK: ;REFERENCE LABEL .IFT ; DF U$$DAS MOV #$RELOC,-(SP) ;PUSH ADDRESS OF RELOCATION ROUTINE .ENDC ; DF U$$DAS MOV #$CKBFR,-(SP) ;AND ADDRESS OF ADDR. CHECK ROUTINE CMPB I.FCN+1-I.PRM(R4),#IO.WLB/400 ;WRITE LOGICAL ? BEQ FACH1 ;IF EQ YES CMPB I.FCN+1-I.PRM(R4),#IO.WVB/400 ;WRITE VIRTUAL ? BEQ FACH1 ;IF EQ YES MOV #$CKBFB,(SP) ;SET READ/WRITE BUFFER CHECK FACH1: MOV (R3)+,R0 ;GET ADDRESS OF USER BUFFER MOVB U.CTL(R5),R1 ;GET CONTROL BYTE BPL 10$ ;IF PL BYTE ALIGNMENT ALLOWED BIT #1,R0 ;IS BUFFER BYTE ALIGNED? BNE 30$ ;IF NE YES-ALIGNMENT ERROR 10$: BIC #^C,R1 ;CLEAR ALL BUT LENGTH MODULO BITS BIT R1,(R3) ;DOES LENGTH HAVE CORRECT MODULUS? BNE 30$ ;IF NE NO-ALIGNMENT EERROR MOV (R3),R1 ;GET LENGTH OF BUFFER IN BYTES BEQ 40$ ;IF EQ ILLEGAL BUFFER 15$: CALL @(SP)+ ;ADDRESS CHECK USER BUFFER BCS 40$ ;IF CS ADDRESS CHECK FAILED .IF DF U$$DAS CALLR @(SP)+ ;RELOCATE BUFFER .IFF ; DF U$$DAS CALLR $RELOC ;RELOCATE USER BUFFER ADDRESS .ENDC ; DF U$$DAS 30$: JMP IEBYT ; 40$: JMP IESPC ;ILLEGAL BUFFER ADDRESS ; ; ADDRESS CHECK I/O BUFFER AND INCREMENT COUNT IN ATTACHMENT DESCRIPTOR ; .ENABL LSB IOBUF: CALL $ACHCK ;ADDRESS CHECK BUFFER BCS 10$ ;IF CS ADDR CHECK FAILURE IOBF2: MOV (R2),R1 ;POINT TO PCB OF BUFER (W.BPCB) INCB P.IOC(R1) ;INDICATE I/O THROUGH PARTITION MOV W.BATT(R2),R1 ;POINT TO ATTACHMENT DESC OF BUFFER INCB A.IOC(R1) ;INCREMENT I/O COUNT 10$: RETURN ; .DSABL LSB .END